package cn.edu.nuaa.aadl2.generatorC.actions;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;

//import org.eclipse.cdt.internal.core.model.CProject;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionDelegate;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;
import org.eclipse.ui.internal.Workbench;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.osate.aadl2.ComponentImplementation;
import org.osate.aadl2.SystemImplementation;
import org.osate.aadl2.instance.SystemInstance;
import org.osate.aadl2.instance.impl.SystemInstanceImpl;
import org.osate.aadl2.modelsupport.resources.OsateResourceUtil;
import org.osate.workspace.IAadlElement;
import org.osate.workspace.IAadlProject;

import cn.edu.nuaa.aadl2.generatorC.ui.Win;

//public class GeneratorAction extends Convert2CprjAbstractHandler implements IObjectActionDelegate {
@SuppressWarnings("restriction")
public class GeneratorAction implements IObjectActionDelegate {
	// private static Logger logger =
	// LogManager.getLogger(GeneratorAction.class.getName());
	/** */
	private Shell shell;
	/** */
	private static String projectname;
	/** */
	private SystemInstance _si = null;
	/** */
	private static MessageConsole console = new MessageConsole("", null);
	/** */
	static boolean exists = false;
	/** */
	private static IProject cproject;
	private static ISelectionService selectionService;

	/**
	 * Constructor for Action1.
	 */
	public GeneratorAction() {
		super();
	}

	/**
	 * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
	 */
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		shell = targetPart.getSite().getShell();
	}

	/**
	 * @see IActionDelegate#run(IAction)
	 */

	public void run(IAction action) {
		GeneratorAction.getConsole().clearConsole();
		if (_si != null) {
			

			preCprjCreate();
			postCprjCreate(cproject);

		} else {

		}
		_si = null;

	}

	/**
	 * @see IActionDelegate#selectionChanged(IAction, ISelection) 鼠标选择监听
	 */
	public void selectionChanged(IAction action, ISelection selection) {
		GeneratorAction.selectionService = Workbench.getInstance().getActiveWorkbenchWindow().getSelectionService();
		if (selection instanceof IStructuredSelection) {
			Object element = ((IStructuredSelection) selection).getFirstElement();

			if (element instanceof IResource) {
				cproject = ((IResource) element).getProject();
			} else if (element instanceof IAadlProject) {
				IAadlProject jProject = ((IAadlElement) element).getAadlProject();
				cproject = jProject.getProject();
			}
		}

		if ((!(selection.isEmpty())) && (selection instanceof IStructuredSelection)) {
			Object obj = ((IStructuredSelection) selection).getFirstElement();
			// System.out.println(obj instanceof IFile);
			if (obj instanceof IFile) {
				final IFile file = (IFile) obj;
				if (file.getFileExtension().toLowerCase().equals("aaxl2")) {
					org.osate.aadl2.instance.SystemInstance model;
					XtextResourceSet resourceSet = OsateResourceUtil.getResourceSet();
					String sp = file.getFullPath().toString();
					Resource resource = resourceSet.getResource(URI.createPlatformResourceURI(sp, false), true);
					if (resource.getContents().size() > 0) {

						model = (org.osate.aadl2.instance.SystemInstance) resource.getContents().get(0);
						_si = model;
						// Template.abolutePathOfSystem=file.getFullPath().toString();
					} else {
						model = null;
					}
					// System.out.println(model);
				}

			}
		}
	}

	public void openConsole() {
		showConsole();
	}

	private static void showConsole() {
		if (console != null) {
			IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();

			IConsole[] existing = manager.getConsoles();
			exists = false;
			for (int i = 0; i < existing.length; i++) {
				if (console == existing[i])
					exists = true;
			}
			if (!exists) {
				manager.addConsoles(new IConsole[] { console });
			}
		}
	}

	public static void closeConsole() {
		IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
		if (console != null) {
			manager.removeConsoles(new IConsole[] { console });
		}
	}

	public static MessageConsole getConsole() {

		showConsole();

		return console;
	}

	public static void printToConsole(String message, boolean activate) {
		MessageConsoleStream printer = GeneratorAction.getConsole().newMessageStream();
		printer.setActivateOnWrite(activate);
		printer.println("��Ϣ" + message);
	}

	public static void printToConsole(String message) {
		MessageConsoleStream printer = GeneratorAction.getConsole().newMessageStream();
		printer.setActivateOnWrite(true);
		printer.println(message);
	}

	public static void printToConsole(Object message) {

		MessageConsoleStream printer = GeneratorAction.getConsole().newMessageStream();

		printer.setActivateOnWrite(true);
		if (message != null)
			printer.println(message.toString());
		else
			printer.println("null");
	}

	public static void printToAllConsole(Object message) {
		MessageConsoleStream printer = GeneratorAction.getConsole().newMessageStream();
		printer.setActivateOnWrite(true);
		if (message != null) {
			printer.println(message.toString());
			java.lang.System.out.println(message.toString());
		} else {
			printer.println("null");
			java.lang.System.out.println("null");
		}
	}

	public static void printToAllConsole() {
		MessageConsoleStream printer = GeneratorAction.getConsole().newMessageStream();
		printer.setActivateOnWrite(true);
		printer.println();
		java.lang.System.out.println();
	}

	public static void printToConsole() {
		MessageConsoleStream printer = GeneratorAction.getConsole().newMessageStream();
		printer.setActivateOnWrite(true);
		printer.println();

	}

	public static IProject getCurrentProject() {
		return cproject;
	}

	public static void createFolderInProject(IProject project, String folderName) {

		IFolder newFolder = project.getFolder(folderName);
		if (!newFolder.exists()) {
			try {
				newFolder.create(true, true, null);
			} catch (CoreException e) {

			}
		} else {
			try {
				newFolder.delete(true, null);
				newFolder.create(true, true, null);
			} catch (CoreException e) {
				e.printStackTrace();
			}

		}
	}

	public static void createFolderAndFileInProject(IProject project, String folderName, String fileName) {

		IFolder newFolder = project.getFolder(folderName);
		if (!newFolder.exists()) {
			try {
				newFolder.create(true, true, null);
			} catch (CoreException e) {
			}
		}
		createFileInFolder(newFolder, fileName);
	}

	public static void createFileInFolder(IFolder folder) {
		IFile newFile = folder.getFile("new_File.txt");
		try {
			File systemFile = null;
			if (newFile.exists())
				newFile.setContents(getInitialContents(), true, false, null);
			else
				systemFile = newFile.getLocation().toFile();

			if (systemFile.exists()) {
				newFile.create(getInitialContents(), false, null);
			} else {
				newFile.create(getInitialContents(), false, null);
			}
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	public static void createFileInFolder(IFolder folder, String fileName) {
		IFile newFile = folder.getFile(fileName);
		try {
			File systemFile = null;
			if (newFile.exists())
				newFile.setContents(getInitialContents(), true, false, null);
			else
				systemFile = newFile.getLocation().toFile();

			if (systemFile.exists()) {
				newFile.create(getInitialContents(), false, null);
			} else {
				newFile.create(getInitialContents(), false, null);
			}
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	// Return input stream used to create initial file contents.
	public static InputStream getInitialContents() {
		StringBuffer sb = new StringBuffer();
		sb.append("My New File Contents");
		return new ByteArrayInputStream(sb.toString().getBytes());
	}

	public static void createFileInFolder(IFolder folder, String fileName, InputStream input) {
		IFile newFile = folder.getFile(fileName);
		try {
			File systemFile = null;
			if (newFile.exists())
				newFile.setContents(input, true, false, null);
			else
				systemFile = newFile.getLocation().toFile();

			if (systemFile.exists()) {
				// skip create -- in file system
				// could refreshLocal on parent at this point
				newFile.create(input, false, null);
			} else {
				newFile.create(input, false, null);
			}
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	public static void createFileAndWriteContentInCorrespondFolder(String folderName, String fileName,
			InputStream input) {
		String[] folders = folderName.split("\\.");
		IProject project = getCurrentProject();
		if (folders.length == 2) {
			IFolder systemFolder = project.getFolder(folders[0]);
			if (systemFolder.exists()) {
				IFolder siFolder = systemFolder.getFolder(folders[1]);
				if (siFolder.exists()) {
					IFile newFile = siFolder.getFile(fileName);
					try {
						File systemFile = null;
						if (newFile.exists())
							newFile.setContents(input, true, false, null);
						else
							systemFile = newFile.getLocation().toFile();

						if (systemFile.exists()) {
							// skip create -- in file system
							// could refreshLocal on parent at this point
							newFile.create(input, false, null);
						} else {
							newFile.create(input, false, null);
						}
					} catch (CoreException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	public static void createFileAndWriteContentInCorrespondFolder(String folderName, String fileName, String str) {
		InputStream input = new ByteArrayInputStream(str.toString().getBytes());
		String[] folders = folderName.split("\\.");
		IProject project = getCurrentProject();
		if (folders.length == 2) {
			IFolder systemFolder = project.getFolder(folders[0]);
			if (systemFolder.exists()) {
				IFolder siFolder = systemFolder.getFolder(folders[1]);
				if (siFolder.exists()) {
					IFile newFile = siFolder.getFile(fileName);
					try {
						File systemFile = null;
						if (newFile.exists())
							newFile.setContents(input, true, false, null);
						else
							systemFile = newFile.getLocation().toFile();

						if (systemFile.exists()) {
							// skip create -- in file system
							// could refreshLocal on parent at this point
							newFile.create(input, false, null);
						} else {
							newFile.create(input, false, null);
						}
					} catch (CoreException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	public static void appendContentInFile(InputStream input) {
	}

	public static void createFolderAndFileInProject(IProject project, String folderName, String fileName,
			InputStream input) {
		IFolder newFolder = project.getFolder(folderName);
		if (!newFolder.exists()) {
			try {
				newFolder.create(true, true, null);
			} catch (CoreException e) {
				// ... ...
				// Deal with Operation
			}
		}

		createFileInFolder(newFolder, fileName, input);
	}

	public static void createFoldersInProject(String folderName) {
		IProject project = getCurrentProject();
		String[] folders = folderName.split("\\.");
		if (folders.length == 2) {
			IFolder systemFolder = project.getFolder(folders[0]);
			if (!systemFolder.exists()) {
				try {
					systemFolder.create(true, true, null);
				} catch (CoreException e) {
					// Deal with Operation
				}
			}
			IFolder siFolder = systemFolder.getFolder(folders[1]);
			if (!siFolder.exists()) {
				try {
					siFolder.create(true, true, null);
				} catch (CoreException e) {
					// Deal with Operation
				}
			} else {
				try {
					siFolder.delete(true, null);
					siFolder.create(true, true, null);
				} catch (CoreException e) {
					e.printStackTrace();
				}
			}

		} else if (folders.length == 1) {

		} else {

		}
	}

	public static void createFolderAndFileInProject(String folderName, String fileName, InputStream input) {
		IProject project = getCurrentProject();
		String[] folders = folderName.split("\\.");
		if (folders.length == 2) {
			IFolder systemFolder = project.getFolder(folders[0]);
			if (!systemFolder.exists()) {
				try {
					systemFolder.create(true, true, null);
				} catch (CoreException e) {
					// ... ...
					// Deal with Operation
				}
			}
			IFolder siFolder = systemFolder.getFolder(folders[1]);
			if (!siFolder.exists()) {
				try {
					siFolder.create(true, true, null);
				} catch (CoreException e) {
					// ... ...
					// Deal with Operation
				}
			} else {
				try {
					siFolder.delete(true, null);
					siFolder.create(true, true, null);
				} catch (CoreException e) {
					e.printStackTrace();
				}
			}
			createFileInFolder(siFolder, fileName, input);

		} else if (folders.length == 1) {

		} else {

		}
	}

	public static void create() {
	}

	SystemImplementation getSystemImplementation2(SystemInstanceImpl _si) {

		for (ComponentImplementation sysi : _si.getInstantiatedObjects()) {
			if (sysi instanceof SystemImplementation) {
				return (SystemImplementation) sysi;
			}
		}
		return null;
	}

	/**
	 * systemInstanceImpl和systemImplementation的关系 Each SystemImplementation is a
	 * ComponentImplementation of SystemInstanceImpl GetInstantiatedObjects()
	 * returns a list of ComponentImplementation
	 */
	public void preCprjCreate() {
		//Tools.setCurrentProject(GeneratorAction.cproject);
		final SystemImplementation sys = getSystemImplementation2((SystemInstanceImpl) _si);
		Win w = new Win(sys,GeneratorAction.cproject);
		w.setVisible(true);

	}

	public void postCprjCreate(IProject cPrj) {
		// TODO Auto-generated method stub
		IWorkspace iw = ResourcesPlugin.getWorkspace();
		IProject project = getCurrentProject();
		String foldername = "C_codes";
		IFolder folder = project.getFolder(foldername);
		try {
			folder.refreshLocal(IResource.DEPTH_ZERO, null);
		} catch (CoreException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	
	}

	public static IProject getGenProject() throws CoreException {
		return null;
	}

}
